/*
* Author: honrun
*/
#include "ch32x035.h"
#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "DevicesDelay.h"
#include "DevicesQueue.h"
#include "DevicesUart.h"


uint8_t g_USART1ReadDMABuff[USART1_DMA_READ_LENGTH] = {0};
uint8_t g_USART2ReadDMABuff[USART2_DMA_READ_LENGTH] = {0};
uint8_t g_USART3ReadDMABuff[USART3_DMA_READ_LENGTH] = {0};


void vUart1Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable COM GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    /* enable USART clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    /* connect port to USARTx_Tx/Rx */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* USART configure */
    USART_DeInit(USART1);
    USART_InitStructure.USART_BaudRate = 921600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStructure);

    vUart1DMAInit();

    /* USART interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable USART interrupt */
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
    USART_ITConfig(USART1, USART_IT_ERR, ENABLE);

    USART_Cmd(USART1, ENABLE);
}

void vUart1DMAInit(void)
{
    DMA_InitTypeDef DMA_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable DMAx */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* deinitialize DMA channelx(USARTx tx) */
    DMA_DeInit(DMA1_Channel4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);

    /* USART DMA enable for transmission */
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

    DMA_Cmd(DMA1_Channel4, ENABLE);

    /* deinitialize DMA channelx(USARTx rx) */
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)g_USART1ReadDMABuff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = USART1_DMA_READ_LENGTH;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    /* USART DMA enable for reception */
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

    DMA_Cmd(DMA1_Channel5, ENABLE);

    /* DMAx interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable DMAx interrupt */
    DMA_ITConfig(DMA1_Channel5, DMA_IT_TC | DMA_IT_HT, ENABLE);
}


void vUart2Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable COM GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    /* enable USART clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    /* connect port to USARTx_Tx/Rx */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* USART configure */
    USART_DeInit(USART2);
    USART_InitStructure.USART_BaudRate = 921600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART2, &USART_InitStructure);

    vUart2DMAInit();

    /* USART interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable USART interrupt */
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
    USART_ITConfig(USART2, USART_IT_ERR, ENABLE);

    USART_Cmd(USART2, ENABLE);
}

void vUart2DMAInit(void)
{
    DMA_InitTypeDef DMA_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable DMAx */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* deinitialize DMA channelx(USARTx tx) */
    DMA_DeInit(DMA1_Channel7);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel7, &DMA_InitStructure);

    /* USART DMA enable for transmission */
    USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

    DMA_Cmd(DMA1_Channel7, ENABLE);

    /* deinitialize DMA channelx(USARTx rx) */
    DMA_DeInit(DMA1_Channel6);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)g_USART2ReadDMABuff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = USART2_DMA_READ_LENGTH;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_Init(DMA1_Channel6, &DMA_InitStructure);

    /* USART DMA enable for reception */
    USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

    DMA_Cmd(DMA1_Channel6, ENABLE);

    /* DMAx interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable DMAx interrupt */
    DMA_ITConfig(DMA1_Channel6, DMA_IT_TC | DMA_IT_HT, ENABLE);
}

void vUart3Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure = {0};
    USART_InitTypeDef USART_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable COM GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    /* enable USART clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

    /* connect port to USARTx_Tx/Rx */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* USART configure */
    USART_DeInit(USART3);
    USART_InitStructure.USART_BaudRate = 921600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_Init(USART3, &USART_InitStructure);

    vUart3DMAInit();

    /* USART interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable USART interrupt */
    USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
    USART_ITConfig(USART3, USART_IT_ERR, ENABLE);

    USART_Cmd(USART3, ENABLE);
}

void vUart3DMAInit(void)
{
    DMA_InitTypeDef DMA_InitStructure = {0};
    NVIC_InitTypeDef  NVIC_InitStructure = {0};

    /* enable DMAx */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    /* deinitialize DMA channelx(USARTx tx) */
    DMA_DeInit(DMA1_Channel2);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART3->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);

    /* USART DMA enable for transmission */
    USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);

    DMA_Cmd(DMA1_Channel2, ENABLE);

    /* deinitialize DMA channelx(USARTx rx) */
    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART3->DATAR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)g_USART2ReadDMABuff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = USART2_DMA_READ_LENGTH;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);

    /* USART DMA enable for reception */
    USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);

    DMA_Cmd(DMA1_Channel3, ENABLE);

    /* DMAx interrupt configuration */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* enable DMAx interrupt */
    DMA_ITConfig(DMA1_Channel3, DMA_IT_TC | DMA_IT_HT, ENABLE);
}

void vUartBaudrateSet(USART_TypeDef *USARTx, int32_t iBaudrate)
{
    RCC_ClocksTypeDef RCC_ClocksStatus;
    uint32_t tmpreg, integerdivider;

    if(iBaudrate < 1)
        return;

    RCC_GetClocksFreq(&RCC_ClocksStatus);

    integerdivider = ((uint32_t)USARTx == USART1_BASE) ? RCC_ClocksStatus.PCLK2_Frequency : RCC_ClocksStatus.PCLK1_Frequency;
    integerdivider = ((25 * integerdivider) / (4 * iBaudrate));

    tmpreg = (integerdivider / 100) << 4;
    integerdivider -= (100 * (tmpreg >> 4));

    tmpreg |= ((((integerdivider * 16) + 50) / 100)) & 0x0F;

    USARTx->BRR = (uint16_t)tmpreg;
}

void vUartSendDatas(USART_TypeDef *USARTx, void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = pvDatas;
    uint32_t uiTime;

    while((iLength--) > 0)
    {
        for(uiTime = 1000; ((RESET == (USARTx->STATR & USART_FLAG_TXE)) && (uiTime > 0)); --uiTime);
        /* Transmit Data */
        USARTx->DATAR = *pucDatas++;
    }

    for(uiTime = 2000; ((RESET == (USARTx->STATR & USART_FLAG_TC)) && (uiTime > 0)); --uiTime);
}

void vUartSendStrings(USART_TypeDef *USARTx, char *pcStrings)
{
    vUartSendDatas(USARTx, pcStrings, strlen(pcStrings));
}


/**
 * @brief  设置DMA的数据传输长度，并启动DMA传输
 * @param  DMAy_Channelx：   相应DMA的通道
           Length：          传输长度
 * @retval 无
 */
void vDmaAddrAndLenthSet(DMA_Channel_TypeDef *DMAy_Channelx, uint32_t uiMemoryBaseAddr, uint32_t uiPeripheralBaseAddr, uint32_t uiLength)
{
    uint32_t uiDMAyFlag = DMA1_FLAG_TC4, uiTime;

    switch((uint32_t)DMAy_Channelx)
    {
        case (uint32_t)DMA1_Channel1: uiDMAyFlag = DMA1_FLAG_GL1 | DMA1_FLAG_TC1 | DMA1_FLAG_HT1 | DMA1_FLAG_TE1; break;
        case (uint32_t)DMA1_Channel2: uiDMAyFlag = DMA1_FLAG_GL2 | DMA1_FLAG_TC2 | DMA1_FLAG_HT2 | DMA1_FLAG_TE2; break;
        case (uint32_t)DMA1_Channel4: uiDMAyFlag = DMA1_FLAG_GL4 | DMA1_FLAG_TC4 | DMA1_FLAG_HT4 | DMA1_FLAG_TE4; break;
        case (uint32_t)DMA1_Channel7: uiDMAyFlag = DMA1_FLAG_GL7 | DMA1_FLAG_TC7 | DMA1_FLAG_HT7 | DMA1_FLAG_TE7; break;

        default : break;
    }

    /* Disable the peripheral */
    DMAy_Channelx->CFGR &= ~DMA_CFGR1_EN;
    for(uiTime = 1000000; ((RESET != (DMAy_Channelx->CFGR & DMA_CFGR1_EN)) && (uiTime > 0)); --uiTime);

    /* 必须要清除所有中断状态，才允许使能DMA */
    DMA_ClearFlag(uiDMAyFlag);

    /* configure memory base address */
    DMAy_Channelx->MADDR = uiMemoryBaseAddr;

    /* configure peripheral base address */
    DMAy_Channelx->PADDR = uiPeripheralBaseAddr;

    /* Configure DMA Stream data length */
    DMAy_Channelx->CNTR = uiLength;

    /* Enable the Peripheral */
    DMAy_Channelx->CFGR |= DMA_CFGR1_EN;
    for(uiTime = 1000000; ((RESET == (DMAy_Channelx->CFGR & DMA_CFGR1_EN)) && (uiTime > 0)); --uiTime);
}

void vUartDMASendDatas(USART_TypeDef *USARTx, void *pvDatas, int32_t iLength)
{
    DMA_Channel_TypeDef *DMAy_Channelx = DMA1_Channel4;
    uint32_t uiDMAyFlag = DMA1_FLAG_TC4, uiTime;

    if(iLength < 1)
        return;

    switch((uint32_t)USARTx)
    {
        case (uint32_t)USART1: DMAy_Channelx = DMA1_Channel4; uiDMAyFlag = DMA1_FLAG_TC4; break;
        case (uint32_t)USART2: DMAy_Channelx = DMA1_Channel7; uiDMAyFlag = DMA1_FLAG_TC7; break;
        case (uint32_t)USART3: DMAy_Channelx = DMA1_Channel2; uiDMAyFlag = DMA1_FLAG_TC2; break;
        case (uint32_t)USART4: DMAy_Channelx = DMA1_Channel1; uiDMAyFlag = DMA1_FLAG_TC1; break;

        default : break;
    }

    /* 设置传输地址与长度，并启动DMA发送 */
    vDmaAddrAndLenthSet(DMAy_Channelx, (uint32_t)pvDatas, (uint32_t)(&USARTx->DATAR), iLength);

    /* 等待本次DMA传输完成 */
    while((DMA_GetFlagStatus(uiDMAyFlag) == RESET)      &&
          ((DMAy_Channelx->CFGR & DMA_CFGR1_EN) != 0)   &&
           (DMAy_Channelx->CNTR > 0)                    &&
          ((iLength--) > 0))
    {
        /* 以9600波特率计算时长 */
        vDelayUs(1500);
    }

    /* 发送2个字节所需时间（9600波特率） */
    uiTime = 2 * 10 * 1000000 / 9600;

    /* 等待全部字节发送完成 */
    while((RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TC)) && (uiTime--))
    {
        vDelayUs(10);
    }
}

void vUartDMASendStrings(USART_TypeDef *USARTx, char *pcStrings)
{
    vUartDMASendDatas(USARTx, pcStrings, strlen(pcStrings));
}

int8_t cUartReceiveByte(USART_TypeDef *USARTx, uint8_t *pucByte)
{
    return cUartReceiveDatas(USARTx, pucByte, 1);
}

int8_t cUartReceiveDatas(USART_TypeDef *USARTx, void *pvDatas, int32_t iLength)
{
    QueueType *ptypeQueueHandle = NULL;

    if(iLength < 1)
        return 1;

    switch((uint32_t)USARTx)
    {
        case (uint32_t)USART1: ptypeQueueHandle = &g_TypeQueueUart1Read; break;
        case (uint32_t)USART2: ptypeQueueHandle = &g_TypeQueueUart2Read; break;
        case (uint32_t)USART3: ptypeQueueHandle = &g_TypeQueueUart3Read; break;

        default : printf("cUartReceiveDatas channel error.\r\n"); return 2;
    }

    /* 判断队列内是否有足够的数据 */
    if(iQueueGetLength(ptypeQueueHandle) < iLength)
        return 3;

    /* 从队列内获取数据 */
    if(enumQueuePopDatas(ptypeQueueHandle, pvDatas, iLength) != queueNormal)
        return 4;

    return 0;
}

int32_t iUartReceiveAllDatas(USART_TypeDef *USARTx, void *pvDatas, int32_t iLengthLimit)
{
    QueueType *ptypeQueueHandle = NULL;
    int32_t iLength = 0;

    if((pvDatas == NULL) || (iLengthLimit < 1))
        return 0;

    switch((uint32_t)USARTx)
    {
        case (uint32_t)USART1: ptypeQueueHandle = &g_TypeQueueUart1Read; break;
        case (uint32_t)USART2: ptypeQueueHandle = &g_TypeQueueUart2Read; break;
        case (uint32_t)USART3: ptypeQueueHandle = &g_TypeQueueUart3Read; break;

        default : printf("cUartReceiveAllDatas channel error.\r\n"); return 0;
    }

    /* 读取队列内有效数据的长度 */
    if((iLength = iQueueGetLength(ptypeQueueHandle)) < 1)
        return 0;

    /* 限制读取长度 */
    iLength = iLength > iLengthLimit ? iLengthLimit : iLength;

    /* 从队列内获取数据 */
    if(enumQueuePopDatas(ptypeQueueHandle, pvDatas, iLength) != queueNormal)
        return 0;

    return iLength;
}

int32_t iUartReceiveLengthGet(USART_TypeDef *USARTx)
{
    QueueType *ptypeQueueHandle = NULL;

    switch((uint32_t)USARTx)
    {
        case (uint32_t)USART1: ptypeQueueHandle = &g_TypeQueueUart1Read; break;
        case (uint32_t)USART2: ptypeQueueHandle = &g_TypeQueueUart2Read; break;
        case (uint32_t)USART3: ptypeQueueHandle = &g_TypeQueueUart3Read; break;

        default : printf("cUartReceiveLengthGet channel error.\r\n"); return 0;
    }

    /* 读取队列内有效数据的长度 */
    return iQueueGetLength(ptypeQueueHandle);
}

int8_t cUartReceiveClear(USART_TypeDef *USARTx)
{
    QueueType *ptypeQueueHandle = NULL;

    switch((uint32_t)USARTx)
    {
        case (uint32_t)USART1: ptypeQueueHandle = &g_TypeQueueUart1Read; break;
        case (uint32_t)USART2: ptypeQueueHandle = &g_TypeQueueUart2Read; break;
        case (uint32_t)USART3: ptypeQueueHandle = &g_TypeQueueUart3Read; break;

        default : printf("cUartReceiveClear channel error.\r\n"); return 1;
    }

    /* 设置队列状态为空 */
    return enumQueueSetState(ptypeQueueHandle, queueEmpty);
}
